class Watcher{
  constructor(expr,vm,cb){
    this.expr = expr;
    this.vm = vm;
    this.cb = cb;
    this.oldVal = this.getOldVal()
  }
  update(){
    const newVal = compileUtil.getVal(this.expr,this.vm);
    if(newVal != this.oldVal){
      this.cb(newVal);
    }
  }
  getOldVal(){
    Dep.target = this;
    const oldVal=compileUtil.getVal(this.expr,this.vm);
    Dep.target = null;
    return oldVal;
  }
}
class Dep{
  constructor(){
    this.subs=[]
  }
  addSub(watcher){
    this.subs.push(watcher);
  }
  notify(){
    this.subs.forEach(watcher=>{
      watcher.update();
    })
  }
}

class Observer{
  constructor(data){
    this.observe(data);
  }
  observe(data){
    console.log('observe');
    if(data&& typeof data === 'object'){
      Object.keys(data).forEach(key => {
        this.defineReactive(data,key,data[key]);
      });
    }
  }
  defineReactive(obj,key,value){
    const self = this;
    //递归
    this.observe(value)
    const dep = new Dep();
    Object.defineProperty(obj,key,{
      enumerable:true,
      configurable:true,
      get(){
        console.log('define get');
        //订阅数据变化时，往dep 中添加观察者
        Dep.target&&dep.addSub(Dep.target);
        return value;
      },
      set(newVal){
        console.log('define set');
        if(value != newVal){
          self.observe(newVal)
          value = newVal;
           //通知变化
          dep.notify();
        }
       
      }
    })
  }
}